/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package md.sv.dbu.mq;

import com.ibm.mq.*;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.Arrays;

public class MQReceiver {
    private static final org.slf4j.Logger logger = LoggerFactory.getLogger(MQReceiver.class);

    MQMessage currentMQMessage;
    private MQQueueManager mqManager;
    private MQQueue mqQueue;
    private MQQueue errorQueue;
    private String manager;
    private String queueFrom;
    private String queueError;

    public MQReceiver(String manager, String queueFrom, String queueError) {
        this.manager = manager;
        this.queueFrom = queueFrom;
        this.queueError = queueError;
        logger.info("manager = {}, queueFrom = {}, queueError = {}", manager, queueFrom, queueError);
    }

    public boolean open() {
        try {
            logger.debug("Opening connection to MQ");
            mqManager = new MQQueueManager(manager);
            int openOptions = MQC.MQOO_INPUT_SHARED | MQC.MQOO_BROWSE | MQC.MQOO_INQUIRE;
            logger.debug("Queue manager initialized..");
            mqQueue = mqManager.accessQueue(queueFrom.trim(), openOptions, null, null, null);
            logger.debug("QueueFrom accessed!");

            int openOptionsERR_Q = MQC.MQOO_INPUT_SHARED | MQC.MQOO_OUTPUT;
            errorQueue = mqManager.accessQueue(queueError.trim(), openOptionsERR_Q, null, null, null);
            logger.debug("QueueError accessed!");

            return true;
        } catch (MQException e) {
            logger.warn("MQ exception: ",e);
            if (e.reasonCode != MQException.MQRC_NO_MSG_AVAILABLE) {
                logger.info("...it's OK, No available messages !!!");
            } else {
                logger.error("...MQException.E={}", e);
            }
            return false;
        }
    }

    public String getMessageFromQueue() {

        MQGetMessageOptions gmo = new MQGetMessageOptions();
        gmo.options = MQC.MQGMO_WAIT | MQC.MQGMO_BROWSE_FIRST | MQC.MQGMO_COMPLETE_MSG;
        gmo.matchOptions = MQC.MQMO_MATCH_MSG_SEQ_NUMBER;
        if (currentMQMessage == null)
            currentMQMessage = new MQMessage();

        currentMQMessage.format = "Byte";
        try {

            if (mqQueue.getCurrentDepth() > 0) {
                // mqQueue.get(currentMQMessage, gmo, i)
                mqQueue.get(currentMQMessage, gmo);
                return currentMQMessage.readStringOfByteLength(currentMQMessage.getMessageLength());
            }
        } catch (Exception e) {
            logger.error("...MQException.E={}", e);
        }
        return null;
    }

    public boolean removeCurrentMessageFromQueue() {
        try {
            if (mqQueue.getCurrentDepth() > 0) {
                mqQueue.get(currentMQMessage, new MQGetMessageOptions());
                logger.error("... Remove mesage ID={}, total numbers is {}"
                        , new Object[]{Arrays.hashCode(currentMQMessage.messageId), mqQueue.getCurrentDepth()});
                currentMQMessage.readStringOfByteLength(currentMQMessage.getMessageLength());
            }
            return true;
        } catch (MQException e) {
            if (e.reasonCode != MQException.MQRC_NO_MSG_AVAILABLE) {
                return true;
            } else {
                logger.error("...MQException.E={}", e);
            }
        } catch (IOException e) {
            logger.error("...MQException.E={}", e);
        }
        return false;
    }

    public void close() {


        try {
            mqQueue.close();
        } catch (MQException e) {
            if (e.reasonCode != MQException.MQRC_NO_MSG_AVAILABLE) {
                logger.error("error", e);
            }
        }

        try {
            errorQueue.close();
        } catch (MQException e) {
            if (e.reasonCode != MQException.MQRC_NO_MSG_AVAILABLE) {
                logger.error("error", e);
            }
        }
        try {
            mqManager.disconnect();
        } catch (MQException e) {
            if (e.reasonCode != MQException.MQRC_NO_MSG_AVAILABLE) {
                logger.error("error", e);
            }
        }

    }

    public boolean moveMessageToErrorQueue() {
        try {
            mqQueue.get(currentMQMessage, new MQGetMessageOptions());
            errorQueue.put(currentMQMessage, new MQPutMessageOptions());

            logger.info("... Remove mesage ID={}, total numbers is {}"
                    , new Object[]{Arrays.hashCode(currentMQMessage.messageId), mqQueue.getCurrentDepth()});

        } catch (MQException e) {
            if (e.reasonCode == MQException.MQRC_NO_MSG_AVAILABLE) {
                return false;
            }
        } catch (Exception e) {
            logger.error("...MQException.E={}", e);
        }
        return true;
    }


}
